ট্রান্সাকশন ম্যানেজমেন্ট (Transaction Management) হলো একাধিক ডেটাবেস অপারেশনকে একটি ইউনিট হিসেবে পরিচালনা করা। যদি এই ইউনিটের মধ্যে কোনো একটি অপারেশন ব্যর্থ হয়, তাহলে পুরো ইউনিটটিকে ব্যর্থ ঘোষণা করা হয় এবং পূর্ববর্তী সকল পরিবর্তন পূর্বাবস্থায় ফেরত (rollback) নেওয়া হয়।
স্প্রিং ফ্রেমওয়ার্কে ট্রান্সাকশন ম্যানেজমেন্টের সুবিধা রয়েছে যা ডেটাবেসের সাথে কাজ করা আরও সহজ এবং নিরাপদ করে তোলে।
Spring ORM এ Hibernate এর সাথে ট্রান্সাকশন ম্যানেজমেন্ট সেটআপ করতে নিম্নলিখিত স্টেপগুলো অনুসরণ করতে হবে।
spring-tx
নির্ভরশীলতা যোগ করাট্রান্সাকশন ব্যবস্থাপনার জন্য Maven প্রজেক্টে spring-tx
নির্ভরশীলতা যুক্ত করতে হবে।
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.12</version>
</dependency>
Spring এ Hibernate ট্রান্সাকশন ম্যানেজার কনফিগার করতে হবে। এটি Spring Bean Configuration ফাইলে যুক্ত করা যেতে পারে।
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven>
ব্যবহারSpring XML ফাইলে ট্রান্সাকশন এনোটেশন সক্রিয় করতে <tx:annotation-driven>
ট্যাগ ব্যবহার করতে হবে।
<tx:annotation-driven transaction-manager="transactionManager" />
@Transactional
এনোটেশন ব্যবহার করে নির্দিষ্ট মেথড বা ক্লাসে ট্রান্সাকশন ম্যানেজমেন্ট প্রয়োগ করা যায়।
package com.example.service;
import com.example.dao.UserDao;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Transactional
public void saveUser(User user) {
userDao.saveUser(user);
}
}
নিম্নে Spring ORM এবং Hibernate এর সাথে ট্রান্সাকশন ম্যানেজমেন্টের একটি উদাহরণ দেওয়া হলো।
package com.example.dao;
import com.example.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
@Autowired
private SessionFactory sessionFactory;
public void saveUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.save(user);
}
public void updateUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.update(user);
}
}
package com.example.service;
import com.example.dao.UserDao;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Transactional
public void saveOrUpdateUser(User user) {
userDao.saveUser(user);
// Example of another database operation in the same transaction
user.setName("Updated Name");
userDao.updateUser(user);
}
}
package com.example;
import com.example.config.AppConfig;
import com.example.model.User;
import com.example.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
userService.saveOrUpdateUser(user);
System.out.println("Transaction completed successfully!");
}
}
@Transactional
এনোটেশনটি সেই মেথডে ব্যবহার করা হয় যেখানে একাধিক ডেটাবেস অপারেশন একই ট্রান্সাকশনের আওতায় পরিচালিত হবে।transactionManager
কনফিগার করা আবশ্যক।Spring ORM এর মাধ্যমে Hibernate এর সাথে ট্রান্সাকশন ম্যানেজমেন্ট খুব সহজ এবং কার্যকরভাবে পরিচালনা করা যায়।
ট্রানজ্যাকশন ম্যানেজমেন্ট হলো ডেটাবেস অপারেশনের একটি অত্যন্ত গুরুত্বপূর্ণ অংশ, যা নিশ্চিত করে যে একটি গ্রুপ ডেটাবেস অপারেশন (যেমন Insert, Update, Delete) একটি একক ইউনিট হিসেবে কার্যকর হচ্ছে। যদি কোনো একটি অপারেশন ব্যর্থ হয়, তাহলে পুরো ট্রানজ্যাকশন বাতিল (Rollback) হয়ে যায় এবং ডেটাবেস আগের অবস্থায় ফিরে যায়।
Spring Framework-এর Transaction Management ডেভেলপারদের জন্য ডেটাবেস অপারেশন পরিচালনা করার একটি সরল এবং কার্যকর উপায় প্রদান করে।
ট্রানজ্যাকশন ম্যানেজমেন্ট চারটি মূল নীতি (ACID Properties) মেনে চলে:
Spring Framework বিভিন্ন ORM (Hibernate, JPA) এবং ডেটাবেসের সঙ্গে সহজে ইন্টিগ্রেশন করার জন্য Transaction Management সরবরাহ করে। এটি Declarative (Annotation বা XML ব্যবহার) এবং Programmatic (কোডের মাধ্যমে) পদ্ধতিতে পরিচালিত হতে পারে।
Spring এর XML ফাইল ব্যবহার করে ট্রানজ্যাকশন কনফিগার করা যায়। উদাহরণস্বরূপ:
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
Java Configuration ব্যবহার করে ট্রানজ্যাকশন ম্যানেজমেন্ট কনফিগার করা হয়। উদাহরণ:
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
}
Spring এ ডিক্লারেটিভ পদ্ধতিতে ট্রানজ্যাকশন ম্যানেজ করার জন্য @Transactional এনোটেশন ব্যবহার করা হয়। এটি ডেটাবেস অপারেশনগুলিকে স্বয়ংক্রিয়ভাবে Rollback বা Commit করতে সাহায্য করে।
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional
public void createUser(User user) {
userRepository.save(user);
}
}
যখন ডেভেলপাররা কোডের মাধ্যমে ট্রানজ্যাকশন পরিচালনা করতে চান, তখন TransactionTemplate বা PlatformTransactionManager ব্যবহার করা হয়।
@Service
public class UserService {
@Autowired
private PlatformTransactionManager transactionManager;
public void createUser(User user) {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
// Perform database operations
userRepository.save(user);
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
throw e;
}
}
}
Spring ORM এ Transaction Management নিশ্চিত করে যে ডেটাবেস অ্যাক্সেস সঠিকভাবে পরিচালিত হচ্ছে এবং এর ফলে ডেটাবেস ব্যতিক্রমী অবস্থায়ও সঠিক অবস্থায় থাকে। এটি একটি ডেটা-ভিত্তিক অ্যাপ্লিকেশনের নির্ভরযোগ্যতা এবং কার্যকারিতা নিশ্চিত করতে অপরিহার্য।
Spring Framework ডেটাবেসের সঙ্গে কাজ করার সময় ট্রানজ্যাকশন পরিচালনার জন্য দুটি পদ্ধতি সরবরাহ করে: Declarative Transaction Management এবং Programmatic Transaction Management। এই পদ্ধতিগুলো Spring ORM, JDBC বা JPA-এর মতো ডেটা অ্যাক্সেস টেকনোলজির সঙ্গে ব্যবহার করা যায়।
Declarative Transaction Management ট্রানজ্যাকশন পরিচালনার জন্য XML বা অ্যানোটেশন কনফিগারেশনের উপর নির্ভর করে। এখানে কোডের মাধ্যমে ট্রানজ্যাকশন ম্যানেজ করার প্রয়োজন হয় না। এটি সাধারণত সহজ ও পরিষ্কার পদ্ধতি এবং Spring Framework-এ সর্বাধিক ব্যবহৃত পদ্ধতি।
@Transactional
public void performTransaction() {
// ডেটাবেস অপারেশন
}
<tx:advice transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
Programmatic Transaction Management হলো একটি পদ্ধতি যেখানে ট্রানজ্যাকশন ম্যানেজমেন্টের জন্য কোড সরাসরি লেখা হয়। এটি জটিল প্রয়োজনে ব্যবহার করা হয় যেখানে ট্রানজ্যাকশন লজিক ডায়নামিক।
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.execute(status -> {
try {
// ডেটাবেস অপারেশন
return null;
} catch (Exception e) {
status.setRollbackOnly();
throw e;
}
});
বৈশিষ্ট্য | Declarative Transaction Management | Programmatic Transaction Management |
---|---|---|
সহজতা | কোড সহজ এবং পরিষ্কার থাকে | কোড জটিল হতে পারে |
কোডের স্থান | ট্রানজ্যাকশন লজিক কোডের বাইরে থাকে | ট্রানজ্যাকশন লজিক কোডের ভেতরে থাকে |
নিয়ন্ত্রণ | সীমিত নিয়ন্ত্রণ প্রদান করে | সম্পূর্ণ নিয়ন্ত্রণ প্রদান করে |
ব্যবহারক্ষেত্র | সাধারণ ট্রানজ্যাকশনের জন্য | জটিল বা ডায়নামিক ট্রানজ্যাকশনের জন্য |
Spring Framework-এ সাধারণত Declarative Transaction Management পদ্ধতি বেশি ব্যবহৃত হয়, কারণ এটি সহজ এবং পরিচ্ছন্ন। তবে জটিলতার ক্ষেত্রে Programmatic Transaction Management কার্যকর হতে পারে।
@Transactional অ্যানোটেশনটি স্প্রিং ফ্রেমওয়ার্কে ট্রানজেকশন ম্যানেজমেন্ট (Transaction Management) পরিচালনার জন্য ব্যবহৃত হয়। এটি ডেটাবেস অপারেশনগুলিকে একটি ইউনিট অফ ওয়ার্ক (Unit of Work) হিসেবে পরিচালনা করে, যেখানে সমস্ত কাজ সফলভাবে সম্পন্ন হলে ডেটাবেসে পরিবর্তনগুলো কার্যকর করা হয়। কোনো ত্রুটি ঘটলে সম্পূর্ণ ট্রানজেকশন বাতিল (Rollback) হয়ে যায়।
@Transactional অ্যানোটেশন ব্যবহার করে স্প্রিং কনটেইনারকে নির্দেশ করা হয় যে, নির্দিষ্ট মেথড বা ক্লাসের মধ্যে থাকা সমস্ত ডেটাবেস অপারেশন একটি ট্রানজেকশনের অংশ। এটি সাধারণত ডেটাবেসে CRUD (Create, Read, Update, Delete) অপারেশনের সময় ব্যবহার করা হয়।
import org.springframework.transaction.annotation.Transactional;
@Service
public class EmployeeService {
@Transactional
public void saveEmployee(Employee employee) {
// Save employee to the database
employeeRepository.save(employee);
}
}
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class EmployeeService {
public void saveEmployee(Employee employee) {
employeeRepository.save(employee);
}
public void deleteEmployeeById(int id) {
employeeRepository.deleteById(id);
}
}
ব্যাখ্যা:
ট্রানজেকশনের প্রসার নির্ধারণ করে। উদাহরণ:
ডেটাবেস আইসোলেশন লেভেল নির্ধারণ করে। উদাহরণ:
ট্রানজেকশন সম্পন্ন হওয়ার জন্য সময়সীমা নির্ধারণ করে।
কোনো নির্দিষ্ট এক্সসেপশনের জন্য রোলব্যাক করার নিয়ম নির্ধারণ করে।
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 5)
public void updateEmployee(Employee employee) {
employeeRepository.save(employee);
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@Transactional
public void transferSalary(int fromEmployeeId, int toEmployeeId, double amount) {
Employee fromEmployee = employeeRepository.findById(fromEmployeeId).orElseThrow();
Employee toEmployee = employeeRepository.findById(toEmployeeId).orElseThrow();
fromEmployee.setSalary(fromEmployee.getSalary() - amount);
toEmployee.setSalary(toEmployee.getSalary() + amount);
employeeRepository.save(fromEmployee);
employeeRepository.save(toEmployee);
}
}
ব্যাখ্যা:
উপরের উদাহরণে, দুটি ডেটাবেস অপারেশন (দুটি এমপ্লয়ির বেতন হালনাগাদ করা) একটি ট্রানজেকশনের অংশ। কোনো একটি অপারেশনে ব্যর্থতা ঘটলে সম্পূর্ণ ট্রানজেকশন রোলব্যাক হবে।
স্প্রিং ফ্রেমওয়ার্কে ট্রানজ্যাকশন ম্যানেজমেন্ট একটি গুরুত্বপূর্ণ বৈশিষ্ট্য। এটি ডেটাবেসে Atomicity, Consistency, Isolation, এবং Durability (ACID) প্রিন্সিপাল মেনে ডেটা পরিচালনা নিশ্চিত করে। স্প্রিং ORM ট্রানজ্যাকশন পরিচালনার জন্য Declarative এবং Programmatic পদ্ধতি প্রদান করে। সাধারণত Declarative পদ্ধতি সবচেয়ে বেশি ব্যবহৃত হয় কারণ এটি সরল ও কার্যকর।
এটি অ্যানোটেশন বা XML কনফিগারেশনের মাধ্যমে ট্রানজ্যাকশন পরিচালনা করে। কোডে কম জটিলতা থাকে এবং সহজেই ট্রানজ্যাকশন পরিচালনা করা যায়।
এটি ম্যানুয়ালি ট্রানজ্যাকশন শুরু এবং শেষ করার জন্য TransactionTemplate বা PlatformTransactionManager ব্যবহার করে।
pom.xml
ফাইলে ডিপেনডেন্সি যোগ করুন:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId> <!-- H2 ডাটাবেস ব্যবহার -->
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String accountHolder;
private Double balance;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAccountHolder() {
return accountHolder;
}
public void setAccountHolder(String accountHolder) {
this.accountHolder = accountHolder;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountRepository extends JpaRepository<Account, Long> {
}
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AccountService {
@Autowired
private AccountRepository accountRepository;
@Transactional
public void transfer(Long fromAccountId, Long toAccountId, Double amount) {
Account fromAccount = accountRepository.findById(fromAccountId).orElseThrow();
Account toAccount = accountRepository.findById(toAccountId).orElseThrow();
if (fromAccount.getBalance() < amount) {
throw new IllegalArgumentException("Insufficient balance");
}
fromAccount.setBalance(fromAccount.getBalance() - amount);
toAccount.setBalance(toAccount.getBalance() + amount);
accountRepository.save(fromAccount);
accountRepository.save(toAccount);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/accounts")
public class AccountController {
@Autowired
private AccountService accountService;
@PostMapping("/transfer")
public String transfer(@RequestParam Long fromAccountId,
@RequestParam Long toAccountId,
@RequestParam Double amount) {
accountService.transfer(fromAccountId, toAccountId, amount);
return "Transfer successful!";
}
}
application.properties
ফাইলে ডাটাবেস কনফিগারেশন যোগ করুন:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
/accounts/transfer
এ ডাটা পাঠান।@Transactional
অ্যানোটেশন ব্যবহার করা হয়েছে, যা নিশ্চিত করে যে ট্রানজ্যাকশন সফল হলে ডাটাবেসে পরিবর্তন সংরক্ষিত হবে। ব্যর্থ হলে সমস্ত অপারেশন রোলব্যাক (Rollback) হবে।স্প্রিং ORM-এ ট্রানজ্যাকশন ম্যানেজমেন্ট সহজ এবং কার্যকর। @Transactional
অ্যানোটেশন ব্যবহার করে Declarative পদ্ধতিতে ডেটাবেস অপারেশন পরিচালনা করা যায়। এটি ডেটা কনসিস্টেন্সি নিশ্চিত করে এবং ডেভেলপারদের জটিল কোড লিখতে হয় না।
Read more